--
-- @Author:      feilong
-- @DateTime:    2018-08-9 23:05:48
-- @Description: 服务间消息处理

local skynet = require "skynet"

local socket = require "skynet.socket"
local httpd = require "http.httpd"
local sockethelper = require "http.sockethelper"
local urllib = require "http.url"
local cjson = require "cjson"

local table = table
local string = string


local MessageHandler = class("MessageHandler")

---------------------------------------------------------
-- Private
---------------------------------------------------------
function MessageHandler:ctor(message_dispatch, node_message)
	
	self.message_dispatch = message_dispatch
	self.node_message = node_message	

	--根目录
	self.web_root = skynet.getenv('pro_path').."/view/layuicms2.0/"
	self:register()

end

--注册本服务里的消息
function MessageHandler:register()

	self.message_dispatch:registerSelf('start', handler(self, self.start))
end

--返回消息给客户端
function MessageHandler:response(id, ...)
	local ok, err = httpd.write_response(sockethelper.writefunc(id), ...)
	if not ok then
		-- if err == sockethelper.socket_error , that means socket closed.
		skynet.error(string.format("fd = %d, %s", id, err))
	end
end

-- 是静态网页文件
function MessageHandler:isStaticFile(path)
	local suffix = path:match("^.+(%.%a+)$")
	-- print("___suffix__",suffix)
	if not suffix or suffix==".lua" then 
		return false
	end
	return true
end

-- 把静态文件返回给客户端
function MessageHandler:openStaticFile(id, file_path)
	local file_path = self.web_root..file_path  
	local file = io.open(file_path, "rb") 
	if not file then
		return self:response(id, 501, "file not exist!")
	end	
	local size = file:seek("end") 
	local header = {}
	header["Content-Length"] = size
	file:seek("set", 0)   
	local data = file:read("*a")
	file:close() 
	self:response(id, 200, data, header)
end

--派发客户端消息，对返回消息处理
function MessageHandler:dispatchClientMessage(id, cmd, ... )
	local res = self.message_dispatch:dispatchMessage(_, _, cmd, ...)
	-- print("_______dispatchClientMessage___res_____",id,res)
	if res and next(res) then 
		local error_msg = global.errorCode:getMessage(res.error_code)
		if error_msg then 
			res.error_msg = error_msg
		end
		self:response(id,200,cjson.encode(res))
		return
	end
	local error_msg = cjson.encode({error_code=-1,error_msg="消息无处理"})	
	self:response(id,200,error_msg)
end


--接收客户端消息
function MessageHandler:start(id, ... )

	socket.start(id)
	-- limit request body size to 8192 (you can pass nil to unlimit)
	local code, url, method, header, body = httpd.read_request(sockethelper.readfunc(id), nil)
	print("_________请求的信息__",code, url)
	print(method, header, body )
	-- print(body.seed_token,"______seed_token")
	if code then
		if code ~= 200 then
			--请求失败
			self:response(id, code)
			socket.close(id)
			return 
		else
			local path, query = urllib.parse(url) --解析url
			-- print("__________________url________",url,path)
			--默认页
			if url == "/" then 
				path = "index.html"
			end
			--静态页面
	   	 	if self:isStaticFile(path) then	   	 		
				self:openStaticFile(id,path)		
				socket.close(id)    
				return
		    end
		    ----------- 需要动态处理的消息-----------
		    local token = header.token 
		    local cmd = path:match(".+%/(.+)$")
		    local param	
		 --    if  cmd~='login' then 	    
			--     if not token then 
			--     	--从redis验证是否存在token, 不存在就先去登录
			--     	self:response(id, code, cjson.encode({status='error',msg='未登录操作'}) )
			-- 		socket.close(id)    
			-- 		return			    	
			--     end
			--     if token then 
			--     	local res = self.node_message:callDbRedis("hgetall", {"token:"..token})			    	
			--     	if not res or not next(res) then 
			--     		self:response(id, code, cjson.encode({status='error',msg='未登录操作'}) )
			--     	end
			-- 		socket.close(id)    
			-- 		return			    	
			--     end
			-- end
		    if query then 
		    	param = urllib.parse_query(query) or {}	
		    	print("__000__param___", param)	    	
		    	for k, v in pairs(param) do 
		    		if type(v)=='string' then 
		    			local ok, res = pcall(cjson.decode, v)
		    			if ok and type(res)=="table" then 
		    				param[k] = res
		    			else
			    			param[k] = v 
			    		end
		    		end
		    	end
		    end
		    print("_111___param___",cmd, param)
		    if string.upper(method)=='POST' then --post 方式上传数据
		    	-- param['post'] = body
		    	param = urllib.parse_query(body) or {}		    	
		    	for k, v in pairs(param) do 
		    		if type(v)=='string' then 
		    			param[k]=v
		    		end
		    	end		    	
		    end
		    print("____param___",cmd, param)
	    	assert(cmd, "cmd is null__________")
		    self:dispatchClientMessage(id, cmd, param)

		end
	else
		if url == sockethelper.socket_error then
			skynet.error("socket closed")
		else
			skynet.error(url)
		end
	end
	socket.close(id)
end




return MessageHandler